package com.aids_malaria.http;

import android.accounts.NetworkErrorException;

import com.aids_malaria.R;
import com.aids_malaria.app.App;
import com.aids_malaria.app.Constant;
import com.aids_malaria.event.Events;
import com.aids_malaria.http.response.BaseResponse;
import com.aids_malaria.util.LogUtil;
import com.aids_malaria.util.ResourceUtil;
import com.aids_malaria.util.SpUtil;
import com.aids_malaria.util.StringUtil;
import com.aids_malaria.util.ToastUtil;
import com.luck.picture.lib.rxbus2.RxBus;

import java.net.ConnectException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.util.concurrent.TimeoutException;

import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
import retrofit2.HttpException;

/**
 * Author: fwp
 * Date: 2019-04-09
 * Description: BaseObserver 封装观察者(请求错误，成功，token过期处理)
 */

public abstract class BaseObserver<T> implements Observer<BaseResponse<T>> {

    public BaseObserver() {
    }

    @Override
    public void onSubscribe(Disposable d) {
        onStart();
    }

    @Override
    public void onNext(BaseResponse<T> tBaseResponse) {
        if(tBaseResponse.isOverToken()){
            try {
                onOverToken(ResourceUtil.getString(R.string.over_token_please_login));
            } catch (Exception e) {
                e.printStackTrace();
                LogUtil.e(e.toString());
            }
        }else if (tBaseResponse.isSuccess()) {
            try {
                onSuccess(tBaseResponse.getData());
                onSuccessWithDataSize(tBaseResponse.getData(),
                        StringUtil.isEmpty(tBaseResponse.getDatasize())?0:Integer.valueOf(tBaseResponse.getDatasize()));
            } catch (Exception e) {
                e.printStackTrace();
                LogUtil.e(e.toString());
            }
        } else {
            try {
                connectError();
                onError(StringUtil.isEmpty(tBaseResponse.getMessage()) ?
                        ResourceUtil.getString(R.string.connect_fail) : tBaseResponse.getMessage());
            } catch (Exception e) {
                e.printStackTrace();
                LogUtil.e(e.toString());
            }
        }
    }

    @Override
    public void onError(Throwable e) {
        LogUtil.e(e.toString());
        try {
            connectError();
            if (e instanceof ConnectException
                    || e instanceof TimeoutException
                    || e instanceof SocketTimeoutException
                    || e instanceof NetworkErrorException
                    || e instanceof HttpException
                    || e instanceof UnknownHostException) {
                onError(ResourceUtil.getString(R.string.net_enable));
            } else {
                onError(ResourceUtil.getString(R.string.connect_fail));
            }
            onFinish();
        } catch (Exception e1) {
            e1.printStackTrace();
        }
    }

    @Override
    public void onComplete() {
        onFinish();
    }

    /**
     * 请求开始返回
     */
    protected abstract void onStart();

    /**
     * 请求数据成功返回
     * @param data
     * @throws Exception
     */
    protected abstract void onSuccess(T data) throws Exception;

    /**
     * 请求数据成功返回
     * @param data
     * @throws Exception
     */
    protected void onSuccessWithDataSize(T data, int dataSize) throws Exception{

    }

    /**
     * 请求数据失败返回
     * @param message
     */
    protected void onError(String message) throws Exception{
        boolean isWOrkModelOnLine = SpUtil.getBoolean(App.getAppContext(), Constant.IS_WORK_MODEL_ON_LINE, true);
        if(isWOrkModelOnLine){
            ToastUtil.showToast(message);
        }
    }

    /**
     * 请求完成返回
     */
    protected abstract void onFinish();

    /**
     * 请求token处理
     * @throws Exception
     */
    protected void onOverToken(String message) throws Exception{
        ToastUtil.showToast(message);
        //RxBus发送通知
        RxBus.getDefault().post(new Events.OverTokenEvent());
    }

    /**
     * 网络连接处理
     * @throws Exception
     */
    protected void isOnLine(boolean isOnLine) throws Exception{
        SpUtil.putBoolean(App.getAppContext(), Constant.IS_LINK_SUCCESS,isOnLine);
        //RxBus发送通知
        RxBus.getDefault().post(new Events.LinkEvent());
    }

    /**
     * 网络连接失败隐藏loading框处理
     * @throws Exception
     */
    protected void connectError() throws Exception{
        //RxBus发送通知
        RxBus.getDefault().post(new Events.ConnectError());
    }



}
